import { Component, OnDestroy } from '@angular/core'
import { FormGroup, FormBuilder } from '@angular/forms'
import { ActivatedRoute } from '@angular/router'
import { Observable, of, BehaviorSubject } from 'rxjs'
import { concatMap, map, tap, delay, shareReplay, take } from 'rxjs/operators'
import { NzMessageService } from 'ng-zorro-antd'

import { Currency } from '@shared/interfaces/common'
import { NewPageAccessor } from '@shared/components/new-page/new-page.interface'
import { makeAllControlDirty } from 'app/utils/helpers'
import { I18NService } from '@core'
import { StoreService } from '../../store.service'
import { ChannelFormService } from '../../components/channel-form/channel-form.service'
import { IQRRouteOfStore, Store } from '@shared/interfaces/store'
import { EPaymentBrand } from '@shared/enums'
import { IChannelMap, EChannelsSwitcherCategory } from '../../components/channels-switcher/channels-switcher.interface'
import { StoreDataService } from '../../store-data.service'
import { DataService } from '@shared/services/data.service'

@Component({
  template: '',
})
export class StoreBaseChannelComponent implements NewPageAccessor, OnDestroy {
  constructor(
    protected msg: NzMessageService,
    protected i18n: I18NService,
    protected fb: FormBuilder,
    protected route: ActivatedRoute,
    protected dataService: DataService,
    protected storeService: StoreService,
    protected storeDataService: StoreDataService,
    protected channelFormService: ChannelFormService,
  ) {}
  data: any
  payload: IQRRouteOfStore

  validateForm: FormGroup = this.fb.group({})
  paymentBrand: EPaymentBrand
  isInsCodeLoaded = false
  isStoreCurrenciesLoaded = false
  category: EChannelsSwitcherCategory

  category$: Observable<EChannelsSwitcherCategory> = this.route.params.pipe(
    map(params => params.category),
    tap(category => (this.category = category)),
  )

  currentStore$: Observable<Store> = this.storeDataService.store$.value$.pipe(
    take(1),
    concatMap(store => {
      if (store && store.common && store.common.intStoreCode) {
        return of(store)
      }

      return this.route.params.pipe(
        concatMap(params => this.storeService.getOne(params.id)),
        map(storeFull => storeFull.store),
      )
    }),
    shareReplay(2),
  )

  insCode$: Observable<string> = this.currentStore$.pipe(
    map(store => store.common.insCode),
    tap(() => {
      this.isInsCodeLoaded = true
      this.checkToStopLoading(this.isInsCodeLoaded, this.isStoreCurrenciesLoaded)
    }),
  )

  storeCurrencies$: Observable<Currency[]> = this.currentStore$.pipe(
    map(store => store.common.currencies),
    tap(() => {
      this.isStoreCurrenciesLoaded = true
      this.checkToStopLoading(this.isInsCodeLoaded, this.isStoreCurrenciesLoaded)
    }),
  )

  channelsMap$: Observable<IChannelMap>
  loadingSubject = new BehaviorSubject(true)
  isLoading$ = this.loadingSubject.asObservable().pipe(delay(0))

  ngOnDestroy(): void {
    // restore current store data inside the dataService
    this.storeDataService.resetStore()
  }

  checkToStopLoading(isInsCodeLoaded: boolean, isStoreCurrenciesLoaded: boolean) {
    if (isInsCodeLoaded && isStoreCurrenciesLoaded) {
      this.loadingSubject.next(false)
    }
  }

  checkValid(): boolean {
    if (this.validateForm.controls.TRU) {
      if (
        this.validateForm.controls.TRU.get('authOnline').value &&
        !this.validateForm.controls.TRU.get('payNearby').value
      ) {
        this.validateForm.controls.TRU.get('shopID').setValue('223')
      }
      if (
        this.validateForm.controls.TRU.get('chanCode').value === EPaymentBrand.TrueMoney &&
        !this.validateForm.controls.TRU.get('authOnline').value &&
        !this.validateForm.controls.TRU.get('payNearby').value
      ) {
        this.msg.error(this.trans('VALID.PAY.MEATHOD.NOE'))
        return false
      }
    }

    if (this.validateForm.valid) {
      this.pushDataToStore()
      this.msg.success(this.trans('GENERAL.NOTIFICATION.VALIDATION_SUCCESS'))
      return true
    }

    makeAllControlDirty(this.validateForm)
    this.msg.error(this.trans('GENERAL.NOTIFICATION.VALIDATION_FAIL'))
    return false
  }

  pushDataToStore(): void {
    const rawData = this.validateForm.value[this.paymentBrand]
    if (!rawData.chanMerParams && this.paymentBrand !== EPaymentBrand.TrueMoney) {
      const channelForm = this.validateForm.get(this.paymentBrand)
      const chanMerParamsForm = channelForm.get('chanMerParams')
      rawData.chanMerParams = chanMerParamsForm.value
    }
    const data = this.channelFormService.convertToIRouteOfStore(this.category, rawData)
    this.payload = data
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }
}
